/***********************************************************************************************************************
*                                                                                                                      *
* SPLASH build system v0.1                                                                                             *
*                                                                                                                      *
* Copyright (c) 2014 Andrew D. Zonenberg                                                                               *
* All rights reserved.                                                                                                 *
*                                                                                                                      *
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the     *
* following conditions are met:                                                                                        *
*                                                                                                                      *
*    * Redistributions of source code must retain the above copyright notice, this list of conditions, and the         *
*      following disclaimer.                                                                                           *
*                                                                                                                      *
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the       *
*      following disclaimer in the documentation and/or other materials provided with the distribution.                *
*                                                                                                                      *
*    * Neither the name of the author nor the names of any contributors may be used to endorse or promote products     *
*      derived from this software without specific prior written permission.                                           *
*                                                                                                                      *
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES        *
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR       *
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE       *
* POSSIBILITY OF SUCH DAMAGE.                                                                                          *
*                                                                                                                      *
***********************************************************************************************************************/

#ifndef AntikernelModuleInfo_h
#define AntikernelModuleInfo_h

/**
	@brief A single bitfield for an AntikernelPacketVariableInfo
 */
class AntikernelPacketBitfield
{
public:
	unsigned int m_word;
	unsigned int m_bithi;
	unsigned int m_bitlo;
	
	AntikernelPacketBitfield(unsigned int w, unsigned int h, unsigned int l)
	 : m_word(w)
	 , m_bithi(h)
	 , m_bitlo(l)
	{ }
};

/**
	@brief Variable info for an RPC packet
	
	varinfo = packinfo[0]
 */
class AntikernelPacketVariableInfo
{
public:
	AntikernelPacketVariableInfo();	
	AntikernelPacketVariableInfo(std::vector<std::string>& lines, unsigned int& i);
	
	///Display name
	std::string m_displayName;
	
	///Long description
	std::string m_desc;	
	
	///Display type
	enum displaytypes
	{
		DISPLAY_TYPE_DEC,		//Decimal integer
		DISPLAY_TYPE_HEX,		//Hex integer
		DISPLAY_TYPE_NOCADDR,	//16-bit NoC address (resolved to hostname)
		DISPLAY_TYPE_PHYADDR,	//48-bit physical address (resolved to host:addr)
		DISPLAY_TYPE_MACADDR,	//48-bit MAC address
		DISPLAY_TYPE_ASCIIZ,	//Null-terminated string (if 8 chars, implicit null)
		DISPLAY_TYPE_IPV6,		//IPv6 address (64 bits max in current implementation)
		DISPLAY_TYPE_ENUM,		//Enumerated constant
		DISPLAY_TYPE_FX8,		//Fixed point with eight fractional bits
		
		DISPLAY_TYPE_LAST		//Invalid tail
		
	} m_displayType;
	
	///Sources of signals
	std::vector<AntikernelPacketBitfield> m_bitfields;
	
	//Enumerated name-value pairs (only for DISPLAY_TYPE_ENUM)
	std::map<unsigned int, std::string> m_enumvals;
	
	void SaveToFile(FILE* fp);
};

/**
	@brief Module API info for Antikernel
	
	Stores information for a single RPC packet format
	
	packinfo = opinfo.m_packetInfo[RPC_TYPE_CALL]
 */
class AntikernelPacketInfo
{
public:
	AntikernelPacketInfo();	
	AntikernelPacketInfo(std::vector<std::string>& lines, unsigned int& i);

	///Opcode name.
	std::string m_opname;
	
	///Long description
	std::string m_desc;
	
	///Array of variables
	std::vector<AntikernelPacketVariableInfo> m_varinfo;
	
	void SaveToFile(FILE* fp);
};

class AntikernelModuleInfo;

/**
	@brief Info for a single RPC opcode, indexed by value
	
	opinfo = graph->modules["NetworkedEthernetMAC"][ETH_SEND_FRAME]
 */
class AntikernelOpcodeInfo
{
public:	
	AntikernelOpcodeInfo();	
	AntikernelOpcodeInfo(std::vector<std::string>& lines, unsigned int& i, AntikernelModuleInfo* parent);

	unsigned int m_funcval;
	std::map<int, AntikernelPacketInfo> m_packetInfo;
	
	void SaveToFile(FILE* fp);
};

/**
	@brief Module information for Antikernel
	
	Stores information for a single module
 */
class AntikernelModuleInfo
{
public:
	AntikernelModuleInfo();
	AntikernelModuleInfo(std::vector<std::string>& lines, unsigned int& i);

	///Table of strings to values
	// OP_FOO = 32'hdeadbeef => m_constants["OP_FOO"] = pair(32, 0xdeadbeef)
	std::map<std::string, std::pair<unsigned int, unsigned int> > m_constants;
	
	///Map of opcode values to protocol decodes
	std::map<unsigned int, AntikernelOpcodeInfo> m_opcodeInfo;
	
	std::string m_name;
	
	void SaveToFile(FILE* fp);
};

#endif
